#include <p24FJ64GA102.h>
#include <PPS.h>
#include "TCPIP Stack/TCPIP.h"

/* Configuration bits
 * See <p24FJ64GA102.h>, at C:\Program Files\Microchip\mplabc30\v3.25\support\PIC24F\h\
 * for more information about the configuration bits available
 */

/* FWDTEN_OFF: Watchdog Timer is disabled - Microchip recommends disabling Watchdog Timer when debugging.
 *   However, it would be good to explore this feature in future projects to reduce power consumption
 * ICS_PGx2: Emulator functions are shared with PGEC2/PGED2 - The pins for programming and debugging are PGEC2 and PGED2
 * JTAGEN_OFF: JTAG port is Disabled - Microchip recommends disabling JTAG when debugging
 */
_CONFIG1(FWDTEN_OFF & JTAGEN_OFF & FWDTEN_OFF & ICS_PGx2);

/* IOL1WAY_OFF: The IOLOCK bit can be set and cleared using the unlock sequence -
 *   This is needed to be able to set Peripherial Pin Select (PPS) to enable Serial Peripherial Interface (SPI) for WiFi communication
 * OSCIOFNC_ON: OSCO pin functions as port I/O (RA3) - CLKO is not used in the project
 * FNOSC_FRCDIV: Fast RC Oscillator with Postscaler (FRCDIV) - Secondary Oscillator is not used in the project
 */
_CONFIG2(IOL1WAY_OFF & OSCIOFNC_ON & FNOSC_FRCDIV);

/* SOSCSEL_IO: SOSC pins have digital I/O functions (RA4, RB4) */
_CONFIG3(SOSCSEL_IO);

/* DSWDTOSC_LPRC: DSWDT uses Low Power RC Oscillator (LPRC) - Secondary Oscillator is not used in the project
 * RTCOSC_LPRC: RTCC uses Low Power RC Oscillator (LPRC) - Secondary Oscillator is not used in the project
 * DSWDTEN_OFF: Deep Sleep Watchdog Timer disabled - It would be good to explore this feature in future projects to reduce power consumption
 */
_CONFIG4(DSWDTOSC_LPRC & RTCOSC_LPRC & DSWDTEN_OFF);


static void initBoard(void);
extern void initStack(void);
void WF_Connect(void);

extern void ledSwitchApp(void);

void mainLedSwitch(void) {
	initBoard();
	
	for(;;) {
		ledSwitchApp();
	}
}

extern void pingApp(void);

void mainPing(void) {
	initBoard();
	initStack();
	WF_Connect();

	for(;;) {
		// This task performs normal stack task including checking
        // for incoming packet, type of packet and calling
        // appropriate stack entity to process it.
        StackTask();

        // This tasks invokes each of the core stack application tasks
        StackApplications();
		
		pingApp();
	}
}

extern void tcpListener(void);

void mainTCPListener(void) {
	initBoard();
	initStack();
	WF_Connect();

	for(;;) {
		// This task performs normal stack task including checking
        // for incoming packet, type of packet and calling
        // appropriate stack entity to process it.
        StackTask();

        // This tasks invokes each of the core stack application tasks
        StackApplications();

		tcpListener();
	}
}

int main(void) {
	//mainLedSwitch();
	//mainPing();
	mainTCPListener();

	return 0;
}

static void initBoard(void) {
	// Use Internal 8 MHz Clock
	OSCCON = 0x0000;
	CLKDIV = 0x0000;

	// Set A/D ports to digital mode
	AD1PCFG = 0xFFFF;

	// Disable comparators
	CM1CON = 0x0000;
	CM2CON = 0x0000;
	CM3CON = 0x0000;

	// Disable PMP (Parallel Master Port)
	PMCON = 0x0000;

	// Disable I2C (Inter-Integrated Circuit)
	I2C1CON = 0x0000;
	I2C2CON = 0x0000;

	// Disable Timer1
	T1CON = 0x0000;

	// Disable REFO (Reference Oscillator Output)
	REFOCON = 0x0000;

	// Disable RTCC (Real-Time Clock and Callendar)
	RCFGCAL = 0x0000;

	// Disable ICN (Interrupt-on-Change)
	CNEN1 = 0x0000;
	CNEN2 = 0x0000;

	// Set PPS(Peripherial Pin Select) Inputs
	PPSUnLock;

	RPINR0bits.INT1R = 7; //RP7 - RB7
	//RPINR20bits.SCK1R = 8; //RP8 - RB8
	RPINR20bits.SDI1R = 6; //SDI1 -- RP6 - RB6
	RPINR21bits.SS1R = 4; //SS1 - RP4 - RB4

	// Set PPS(Peripherial Pin Select) Outputs
	RPOR4bits.RP9R = 7; //SPI1 Data Output (code 7) -- SDO1 -- pin18 -- RP9
	RPOR4bits.RP8R = 8; //SPI1 Clock Output (code 8) -- SCK1OUT -- pin17 -- RP8
	RPOR2bits.RP4R = 9; //SPI1 Slave Select Output (code 9) -- SS1OUT -- pin11 -- RP4

	PPSLock;

	// Set input ports
	TRISBbits.TRISB0 = 1; //Set RB0 == Switch 1 as input
	TRISBbits.TRISB1 = 1; //Set RB1 == Switch 2 as input
	TRISBbits.TRISB2 = 1; //Set RB2 == Switch 3 as input

	// Set output ports
	TRISBbits.TRISB15 = 0; //Set RB15 == LED1 as output
	TRISBbits.TRISB14 = 0; //Set RB14 == LED2 as output
	TRISBbits.TRISB13 = 0; //Set RB13 == LED3 as output

	// Set Wi-Fi WP low (MRF24WBM0 datasheet)
	TRISBbits.TRISB5 = 0; //Set RB5 == WP as output
	PORTBbits.RB5 = 0; //Set WP low

}
